home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
wasm223.zip
/
XMODEM1.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-05-04
|
13KB
|
452 lines
;*************************************;
; WASM Xmodem Support, Basic ;
; By Eric Tauck ;
; ;
; Defines: ;
; ;
; XmdPutH xmodem send handshake ;
; XmdPut xmodem send block ;
; XmdRep wait for a reply ;
; XmdGetH xmodem receive handshake ;
; XmdGet xmodem receive block ;
; XmdClr clear the input pipe ;
; ;
; Requires: ;
; ;
; CHECK1.ASM ;
; CHECK3.ASM ;
; SERIAL1.ASM ;
; SERIAL2.ASM ;
; SERIAL3.ASM ;
; SERIAL4.ASM ;
; SERIAL5.ASM ;
; SERIAL6.ASM ;
;*************************************;
jmp _xmodem1_end
;--- receive block return codes
XMODEM_128 EQU 0 ;received a 128 byte block
XMODEM_1024 EQU 1 ;received a 1024 byte block
XMODEM_TIME EQU 2 ;timeout error
XMODEM_HEADER EQU 3 ;bad block header
XMODEM_NUMBER EQU 4 ;block number error
XMODEM_LAST EQU 5 ;last block number
XMODEM_WRONG EQU 6 ;wrong block number
XMODEM_CHECK EQU 7 ;checksum error
XMODEM_REPLY EQU 8 ;bad reply
XMODEM_NAKED EQU 9 ;remote error (NAK)
XMODEM_END EQU 10 ;end of file (EOT)
;--- block flags
XMODEM_CRC EQU 01H ;16 bit CRC flag (otherwise 8 bit checksum)
XMODEM_BIG EQU 02H ;1024 byte block (otherwise 128 bytes)
XMODEM_FAST EQU 04H ;fast timer values (BBS's, micro-micro, etc)
XMODEM_EOF EQU 08H ;end of file (used internally)
;--- character constants
XMODEM_SOH EQU 1 ;start of 128 byte block
XMODEM_STX EQU 2 ;start of 1024 byte block
XMODEM_ACK EQU 6 ;acknowledge
XMODEM_NAK EQU 21 ;negative acknowledge
XMODEM_EOT EQU 4 ;end of transmission
;--- timer values
_XMOD_SLOW1 EQU 180 ;slow start of block timeout
_XMOD_SLOW2 EQU 90 ;slow middle of block timeout
_XMOD_SLOW3 EQU 68 ;purge timeout 1
_XMOD_SLOW4 EQU 90 ;purge timeout 2
_XMOD_SLOW5 EQU 180 ;reply timeout
_XMOD_SLOW6 EQU 180 ;handshake send timeout
_XMOD_SLOW7 EQU 90 ;handshake receive timeout
_XMOD_FAST1 EQU 36 ;fast start of block timeout
_XMOD_FAST2 EQU 18 ;fast middle of block timeout
_XMOD_FAST3 EQU 14 ;purge timeout 1
_XMOD_FAST4 EQU 18 ;purge timeout 2
_XMOD_FAST5 EQU 36 ;reply timeout
_XMOD_FAST6 EQU 180 ;handshake send timeout
_XMOD_FAST7 EQU 90 ;handshake receive timeout
;========================================
; Xmodem send handshake.
;
; In: BX= record address; CL= flags.
;
; Out: CL= updated; AL= result; CY= set
; if error.
XmdPutH PROC NEAR
;--- time to wait
mov ax, _XMOD_FAST6 ;fast time values
test cl, XMODEM_FAST ;check if fast
jnz _xdouh1 ;jump if so
mov ax, _XMOD_SLOW6 ;slow time values
_xdouh1 push cx
call ComWai ;wait for byte
pop cx
jc _xdouh3
;--- check if CRC enabled
sub ah, ah ;clear bit
cmp al, XMODEM_NAK ;check if non-CRC symbol
je _xdouh2
test cl, XMODEM_CRC ;check if CRC enabled
jz _xdouh4 ;jump if not
cmp al, 'C' ;CRC symbol
jne _xdouh4
mov ah, XMODEM_CRC ;set bit
_xdouh2 and cl, NOT XMODEM_CRC ;clear bit
or cl, ah
mov al, cl ;return bits
clc
ret
;--- timeout
_xdouh3 mov al, XMODEM_TIME
stc
ret
;--- bad handshake code
_xdouh4 mov al, XMODEM_REPLY
stc
ret
ENDP
;========================================
; Send an xmodem block.
;
; In: BX= record address; AX= data
; address; CH= block number; CL=
; flags.
XmdPut PROC NEAR
push di
push si
mov di, bx
mov si, cx
push ax ;save for later
;--- block header
mov al, XMODEM_SOH ;128 byte block header
test si, XMODEM_BIG ;check if big block
jz _xdput1 ;skip if not
mov al, XMODEM_STX ;1024 byte block header
_xdput1 mov bx, di ;record address
call ComPut ;send byte
;--- block number
mov ax, si ;block number in AH
mov al, 255
sub al, ah ;calculate complement
mov bx, di ;record address
call ComPutW ;send word
;--- data
pop ax ;restore data address
mov cx, 128 ;128 bytes
test si, XMODEM_BIG ;check if big block
jz _xdput2 ;skip if not
mov cx, 1024 ;1024 bytes
_xdput2 push ax
push cx
mov bx, di ;record address
call ComWri ;write data
pop cx
pop bx
;--- checksum
mov ax, OFFSET SumBlk ;standard checksum
mov dx, OFFSET ComPut ;output byte
test si, XMODEM_CRC ;check if CRC
jz _xdput3 ;jump if not
mov ax, OFFSET CrcBlk ;CRC
mov dx, OFFSET ComPutW ;output word
_xdput3 push dx
call ax ;calculate checksum
pop dx
mov bx, di ;serial record
call dx ;send byte or word
;--- finished
pop si
pop di
ret
ENDP
;========================================
; Wait for reply.
;
; In: BX= record address; CL= flags.
;
; Out: AL= code; CY= set if error.
XmdRep PROC NEAR
mov ax, _XMOD_FAST5 ;fast time values
test cl, XMODEM_FAST ;check if fast
jnz _xdrep1 ;jump if so
mov ax, _XMOD_SLOW5 ;slow time values
_xdrep1 call ComWai ;wait for reply
jc _xdrep2 ;jump if no timeout
cmp al, XMODEM_NAK ;check if NAK
je _xdrep3 ;jump if so
cmp al, XMODEM_ACK ;check if ACK
jne _xdrep4 ;jump if not
clc
ret
;--- timeout
_xdrep2 mov al, XMODEM_TIME ;timeout error
ret
;--- NAK
_xdrep3 mov al, XMODEM_NAKED ;remote error
stc
ret
;--- invalid reply
_xdrep4 mov al, XMODEM_REPLY ;invalid reply
stc
ret
ENDP
;========================================
; Xmodem recieve handshake.
;
; In: BX= record address; CL= flags.
;
; Out: AL= result; CY= set if error.
XmdGetH PROC NEAR
push di
push si
mov di, bx
;--- time to wait
mov si, _XMOD_FAST7 ;fast time values
test cl, XMODEM_FAST ;check if fast
jnz _xdinh1 ;jump if so
mov si, _XMOD_SLOW7 ;slow time values
;--- check if CRC enabled
_xdinh1 mov al, XMODEM_NAK ;non-CRC symbol
test cl, XMODEM_CRC ;check if CRC enabled
jz _xdinh2 ;jump if not
mov al, 'C' ;CRC symbol
;--- send byte
_xdinh2 mov bx, di ;record address
call ComPut ;send byte
;--- wait for reply
mov ax, si ;time to wait
mov bx, di ;record address
call ComAny ;wait for start of data block
mov al, XMODEM_TIME ;only possible error
pop si
pop di
ret
ENDP
;========================================
; Receive an xmodem block.
;
; In: BX= record address; AX= data
; address; CH= block number; CL=
; flags.
;
; Out: AL= result; CY= set if error.
XmdGet PROC NEAR
push di
push si
push bp
mov di, bx
mov si, cx
push ax
;--- block header
mov ax, _XMOD_FAST1 ;fast time values
mov bp, _XMOD_FAST2 ;
test cl, XMODEM_FAST ;check if fast
jnz _xdget1 ;jump if so
mov ax, _XMOD_SLOW1 ;slow time values
mov bp, _XMOD_SLOW2 ;
_xdget1 mov bx, di ;record address
call ComWai ;wait for header
jc _xdget3 ;timeout
cmp al, XMODEM_EOT ;check if end of transmission
je _xdgetA
mov cx, 128 ;bytes of data
cmp al, XMODEM_SOH ;check if 128 byte block
je _xdget2
test si, XMODEM_BIG ;check if STX allowed
jz _xdget4
cmp al, XMODEM_STX ;check if 1024 byte block
jne _xdget4
mov cx, 1024 ;bytes of data
;--- block number
_xdget2 push cx
mov ax, bp
mov bx, di
call ComWaiW ;wait for a word
pop cx
jc _xdget3 ;jump if timeout
add al, ah
cmp al, 255 ;check if proper complement
jne _xdget5
mov dx, si
cmp ah, dh ;check if right block number
je _xdgetB
dec dh ;previous block number
cmp ah, dh ;check numbers
je _xdget6
jmps _xdget7
;--- errors
_xdget3 mov al, XMODEM_TIME ;timeout
jmps _xdget9
_xdget4 mov al, XMODEM_HEADER ;bad header
jmps _xdget9
_xdget5 mov al, XMODEM_NUMBER ;number complement error
jmps _xdget9
_xdget6 mov al, XMODEM_LAST ;last block number
jmps _xdget9
_xdget7 mov al, XMODEM_WRONG ;wrong block number
jmps _xdget9
_xdget8 mov al, XMODEM_CHECK ;bad checksum
_xdget9 pop cx ;fix stack
pop bp
pop si
pop di
stc
ret
;--- end of transmission
_xdgetA pop ax
mov al, XMODEM_END ;return code
push ax
jmps _xdgetE
;--- restore data location and save return block size
_xdgetB pop ax ;data address
mov dl, XMODEM_128 ;128 byte block
cmp cx, 128 ;check if 128 bytes
je _xdgetC ;skip if so
mov dl, XMODEM_1024 ;must be 1024 byte block
_xdgetC push dx ;save for return
;--- data
push ax
push cx
mov bx, di
mov dx, bp
call ComRea ;read bytes
pop cx
pop bx
jc _xdget3 ;jump if timeout
;--- standard checksum
test si, XMODEM_CRC ;check if CRC
jnz _xdgetD ;jump if so
call SumBlk ;calculate standard checksum
push ax ;save it
mov bx, di
mov ax, bp
call ComWai ;get checksum
pop dx
jc _xdget3 ;jump if timeout
cmp al, dl ;check checksum
jne _xdget8 ;jump if error
jmps _xdgetE
;--- CRC
_xdgetD call CrcBlk ;calculate CRC
push ax ;save it
mov bx, di
mov ax, bp
call ComWaiW ;get checksum
pop dx
jc _xdget3 ;jump if timeout
cmp ax, dx ;check checksum
jne _xdget8 ;jump if error
_xdgetE pop ax
pop bp
pop si
pop di
clc
ret
ENDP
;========================================
; Clear pipe.
;
; In: BX= record address; CL= flags.
;
; Out: CY= set if unable to clear.
XmdClr PROC NEAR
mov ax, _XMOD_FAST3 ;fast time values
mov dx, _XMOD_FAST4 ;
test cl, XMODEM_FAST ;check if fast
jnz _xdclr1 ;jump if so
mov ax, _XMOD_SLOW3 ;slow time values
mov dx, _XMOD_SLOW4 ;
_xdclr1 call ComEmp ;empty pipe
ret
ENDP
_xmodem1_end